package io.github.guojiaxing1995.easyJmeter.common.jmeter;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import io.github.guojiaxing1995.easyJmeter.model.JFileDO;
import io.github.guojiaxing1995.easyJmeter.model.ReportDO;
import io.github.guojiaxing1995.easyJmeter.model.TaskDO;
import io.github.guojiaxing1995.easyJmeter.service.JFileService;
import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.nio.ByteBuffer;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicLong;

@Slf4j
public class FastJtlProcessor {
    // 增大缓冲区提高IO性能
    private static final int BUFFER_SIZE = 64 * 1024 * 1024; // 提升到64MB缓冲区

    // 分段处理的行数，每处理这么多行输出一次进度
    private static final int CHUNK_SIZE = 2000000; // 增加到200万行，进一步减少日志输出频率

    // 用于百分位计算的最大样本数（采样策略）
    private static final int MAX_PERCENTILE_SAMPLES = 1000; // 进一步减少样本数以加快处理速度

    // 时间序列数据点的最大数量（防止图表过密）
    private static final int MAX_TIME_SERIES_POINTS = 50; // 减少数据点以加快图表生成

    // 采样率，控制时间序列数据的采样频率
    private static final int TIME_SERIES_SAMPLING_RATE = 500; // 大幅降低采样率

    // 极限采样率：对于大型文件，只处理其中的一部分数据
    private static final int EXTREME_SAMPLING_RATE = 200; // 每200行只处理1行
    
    // 超级极限采样率：对于超大文件(GB级别)，采用更激进的采样
    private static final int SUPER_EXTREME_SAMPLING_RATE = 500; // 每500行只处理1行
    
    // 极限模式的文件大小阈值，单位：MB
    private static final long EXTREME_MODE_THRESHOLD_MB = 300; // 超过300MB激活极限模式
    
    // 超级极限模式的文件大小阈值，单位：MB
    private static final long SUPER_EXTREME_MODE_THRESHOLD_MB = 1000; // 超过1GB激活超级极限模式
    
    // 是否跳过时间序列数据收集(针对大文件)
    private static final boolean SKIP_TIME_SERIES_FOR_LARGE_FILES = true;
    
    // 是否使用快速解析模式
    private static final boolean USE_FAST_PARSING = true;
    
    /**
     * 快速处理JTL文件，生成统计数据和图表
     * @param taskDO 任务信息
     * @param jtlPath JTL文件路径
     * @param outputDir 输出目录（可选，如果需要输出预处理统计文件）
     * @return 处理结果，包含JSON格式的统计数据
     */
    public JSONObject processFast(TaskDO taskDO, String jtlPath, String outputDir) {
        log.info("开始快速处理JTL文件: {}", jtlPath);
        long startTime = System.currentTimeMillis();

        File jtlFile = new File(jtlPath);
        if (!jtlFile.exists()) {
            log.error("JTL文件不存在: {}", jtlPath);
            return null;
        }

        long fileSizeMB = jtlFile.length() / (1024 * 1024);
        log.info("JTL文件大小: {}MB", fileSizeMB);
        
        // 判断处理模式
        boolean extremeMode = fileSizeMB > EXTREME_MODE_THRESHOLD_MB;
        boolean superExtremeMode = fileSizeMB > SUPER_EXTREME_MODE_THRESHOLD_MB;
        int samplingRate = superExtremeMode ? SUPER_EXTREME_SAMPLING_RATE : 
                           (extremeMode ? EXTREME_SAMPLING_RATE : 1);
        
        // 对于大文件，可以考虑跳过时间序列数据收集
        boolean skipTimeSeries = SKIP_TIME_SERIES_FOR_LARGE_FILES && fileSizeMB > EXTREME_MODE_THRESHOLD_MB;
        
        if (superExtremeMode) {
            log.info("文件大小超过{}MB，启用超级极限采样模式(1/{})", SUPER_EXTREME_MODE_THRESHOLD_MB, SUPER_EXTREME_SAMPLING_RATE);
        } else if (extremeMode) {
            log.info("文件大小超过{}MB，启用极限采样模式(1/{})", EXTREME_MODE_THRESHOLD_MB, EXTREME_SAMPLING_RATE);
        }
        
        if (skipTimeSeries) {
            log.info("大文件模式：跳过时间序列数据收集以提高性能");
        }

        try {
            // 主要统计数据结构
            JSONObject resultJson = new JSONObject();
            Map<String, SamplerStatistics> samplerStats = new ConcurrentHashMap<>();

            // 初始化总体统计
            samplerStats.put("Total", new SamplerStatistics());

            // 时间范围
            AtomicLong firstTimestamp = new AtomicLong(Long.MAX_VALUE);
            AtomicLong lastTimestamp = new AtomicLong(0);

            // 记录总请求数和错误数
            AtomicLong totalSamples = new AtomicLong(0);
            AtomicLong totalErrors = new AtomicLong(0);

            // 每个采样器的时间序列数据
            Map<String, Map<Long, TimePoint>> timeSeriesMap = skipTimeSeries ? 
                    null : new ConcurrentHashMap<>();

            // 读取和解析JTL文件
            int availableProcessors = Runtime.getRuntime().availableProcessors();
            int numThreads = Math.max(4, availableProcessors); // 使用所有可用CPU，甚至可能过度订阅
            log.info("可用处理器数量: {}, 将使用 {} 个线程进行处理", availableProcessors, numThreads);
            
            // 使用内存映射处理大文件
            processJtlFileWithMemoryMapping(jtlPath, samplerStats, timeSeriesMap, firstTimestamp, lastTimestamp,
                    totalSamples, totalErrors, numThreads, samplingRate, skipTimeSeries);

            // 构建结果JSON
            resultJson.put("totalSamples", totalSamples.get());
            resultJson.put("totalErrors", totalErrors.get());
            resultJson.put("firstTimestamp", firstTimestamp.get());
            resultJson.put("lastTimestamp", lastTimestamp.get());

            // 添加每个采样器的统计数据
            JSONObject samplersJson = new JSONObject();
            for (Map.Entry<String, SamplerStatistics> entry : samplerStats.entrySet()) {
                String samplerName = entry.getKey();
                SamplerStatistics stats = entry.getValue();

                JSONObject samplerJson = new JSONObject();
                samplerJson.put("label", samplerName);
                samplerJson.put("samples", stats.getSampleCount());
                samplerJson.put("errors", stats.getErrorCount());
                samplerJson.put("minTime", stats.getMinResponseTime());
                samplerJson.put("maxTime", stats.getMaxResponseTime());
                samplerJson.put("avgTime", stats.getAverageResponseTime());
                samplerJson.put("errorRate", stats.getErrorRate());
                samplerJson.put("receivedBytes", stats.getReceivedBytes());
                samplerJson.put("sentBytes", stats.getSentBytes());

                // 添加百分位数据
                JSONObject percentilesJson = new JSONObject();
                percentilesJson.put("50.0", stats.getPercentile(50));
                percentilesJson.put("90.0", stats.getPercentile(90));
                percentilesJson.put("95.0", stats.getPercentile(95));
                percentilesJson.put("99.0", stats.getPercentile(99));
                samplerJson.put("percentiles", percentilesJson);

                // 添加时间序列数据
                if (!skipTimeSeries && timeSeriesMap != null && timeSeriesMap.containsKey(samplerName)) {
                    samplerJson.put("timeSeriesData", generateTimeSeriesData(timeSeriesMap.get(samplerName)));
                }

                samplersJson.put(samplerName, samplerJson);
            }
            resultJson.put("samplers", samplersJson);

            // 如果指定了输出目录，则保存预处理统计文件
            if (outputDir != null) {
                String statsFilePath = Paths.get(outputDir,
                        "stats_" + taskDO.getTaskId() + "_" + System.currentTimeMillis() + ".json").toString();
                try (FileWriter writer = new FileWriter(statsFilePath)) {
                    writer.write(resultJson.toJSONString());
                    log.info("统计数据已保存至: {}", statsFilePath);
                }
            }

            log.info("快速处理完成，耗时: {}秒", (System.currentTimeMillis() - startTime) / 1000.0);
            return resultJson;

        } catch (Exception e) {
            log.error("处理JTL文件失败: {}", e.getMessage(), e);
            return null;
        }
    }
    
    /**
     * 使用内存映射文件和极限采样处理大型JTL文件
     */
    private void processJtlFileWithMemoryMapping(String jtlPath, Map<String, SamplerStatistics> samplerStats,
                                               Map<String, Map<Long, TimePoint>> timeSeriesMap,
                                               AtomicLong firstTimestamp, AtomicLong lastTimestamp,
                                               AtomicLong totalSamples, AtomicLong totalErrors,
                                               int numThreads, int samplingRate, boolean skipTimeSeries) throws IOException, InterruptedException {
        long processStart = System.currentTimeMillis();
        File file = new File(jtlPath);
        long fileSize = file.length();
        
        // 获取标题行以便解析
        String headerLine;
        try (BufferedReader reader = new BufferedReader(new FileReader(jtlPath), BUFFER_SIZE)) {
            headerLine = reader.readLine();
        }
        
        if (headerLine == null) {
            throw new IOException("JTL文件为空");
        }
        
        // 解析标题行找到各字段的索引
        String[] headers = headerLine.split(",");
        int labelIndex = findColumnIndex(headers, "label");
        int elapsedIndex = findColumnIndex(headers, "elapsed");
        int successIndex = findColumnIndex(headers, "success");
        int timestampIndex = findColumnIndex(headers, "timeStamp", true);
        int bytesIndex = findColumnIndex(headers, "bytes", true);
        int sentBytesIndex = findColumnIndex(headers, "sentBytes", true);
        
        // 使用内存映射文件进行处理
        try (RandomAccessFile randomAccessFile = new RandomAccessFile(file, "r")) {
            // 跳过标题行，获取其长度
            String headerLineWithNewline = headerLine + "\n";
            long headerLength = headerLineWithNewline.length();
            
            // 计算每个线程处理的文件块大小
            long chunkSize = (fileSize - headerLength) / numThreads;
            
            // 创建线程池并初始化任务列表
            ExecutorService executorService = Executors.newFixedThreadPool(numThreads);
            List<Future<?>> futures = new ArrayList<>();
            
            // 为每个线程分配一个文件块
            for (int i = 0; i < numThreads; i++) {
                long start = headerLength + i * chunkSize;
                long end = (i == numThreads - 1) ? fileSize : headerLength + (i + 1) * chunkSize;
                
                futures.add(executorService.submit(() -> {
                    try {
                        processFileChunkWithMemoryMapping(file, start, end, samplerStats, timeSeriesMap, 
                                firstTimestamp, lastTimestamp, totalSamples, totalErrors,
                                labelIndex, elapsedIndex, successIndex, timestampIndex, bytesIndex, sentBytesIndex,
                                samplingRate, skipTimeSeries);
                    } catch (IOException e) {
                        log.error("使用内存映射处理文件块失败: {}", e.getMessage());
                    }
                }));
            }
            
            // 等待所有线程完成
            for (Future<?> future : futures) {
                try {
                    future.get();
                } catch (Exception e) {
                    log.error("等待线程完成时发生错误: {}", e.getMessage());
                }
            }
            
            executorService.shutdown();
        }
        
        // 模拟真实样本总数，因为极限采样只处理了部分数据
        if (totalSamples.get() > 0 && samplingRate > 1) {
            long estimatedTotalSamples = totalSamples.get() * samplingRate;
            long estimatedTotalErrors = totalErrors.get() * samplingRate;
            log.info("估算样本总数: 实际处理 {} 样本，估算总量 {} 样本", totalSamples.get(), estimatedTotalSamples);
            totalSamples.set(estimatedTotalSamples);
            totalErrors.set(estimatedTotalErrors);
            
            // 同时调整各采样器的统计数据
            for (SamplerStatistics stats : samplerStats.values()) {
                stats.adjustForSampling(samplingRate);
            }
        }
        
        log.info("使用内存映射和极限采样模式处理JTL文件完成，耗时: {}秒", (System.currentTimeMillis() - processStart) / 1000.0);
    }
    
    /**
     * 使用内存映射处理文件的某个块
     */
    private void processFileChunkWithMemoryMapping(File file, long start, long end,
                                                 Map<String, SamplerStatistics> samplerStats,
                                                 Map<String, Map<Long, TimePoint>> timeSeriesMap,
                                                 AtomicLong firstTimestamp, AtomicLong lastTimestamp,
                                                 AtomicLong totalSamples, AtomicLong totalErrors,
                                                 int labelIndex, int elapsedIndex, int successIndex,
                                                 int timestampIndex, int bytesIndex, int sentBytesIndex,
                                                 int samplingRate, boolean skipTimeSeries) throws IOException {
        
        // 文件太小，无需处理
        if (end - start <= 0) {
            return;
        }
        
        long processedLines = 0;
        long processStart = System.currentTimeMillis();
        int samplingCounter = 0; // 用于极限采样
        
        try (FileInputStream fis = new FileInputStream(file);
             FileChannel channel = fis.getChannel()) {
            
            // 调整起始位置到下一个完整行
            long adjustedStart = start;
            if (start > 0) {
                adjustedStart = findNextLineStart(channel, start);
            }
            
            // 调整结束位置到完整行结束
            long adjustedEnd = findNextLineStart(channel, end);
            if (adjustedEnd == -1) {
                adjustedEnd = end;
            }
            
            // 计算映射大小
            long size = adjustedEnd - adjustedStart;
            
            // 映射文件到内存
            MappedByteBuffer buffer = channel.map(FileChannel.MapMode.READ_ONLY, adjustedStart, size);
            
            // 处理数据
            StringBuilder line = new StringBuilder(1000); // 预分配合理大小
            byte b;
            
            while (buffer.hasRemaining()) {
                b = buffer.get();
                
                if (b == '\n') {
                    String lineStr = line.toString();
                    line.setLength(0);
                    
                    // 极限采样模式：只处理部分数据
                    samplingCounter++;
                    if (samplingCounter % samplingRate != 0) {
                        continue;
                    }
                    
                    processedLines++;
                    
                    if (processedLines % CHUNK_SIZE == 0) {
                        log.info("线程处理区域 [{}-{}]: 已处理 {} 行数据，耗时: {}秒",
                                adjustedStart, adjustedEnd, processedLines, (System.currentTimeMillis() - processStart) / 1000.0);
                    }
                    
                    try {
                        // 使用快速解析而非split
                        if (USE_FAST_PARSING) {
                            processLineWithFastParsing(lineStr, samplerStats, timeSeriesMap, firstTimestamp, lastTimestamp,
                                totalSamples, totalErrors, labelIndex, elapsedIndex, successIndex, timestampIndex,
                                bytesIndex, sentBytesIndex, processedLines, skipTimeSeries);
                        } else {
                            String[] values = lineStr.split(",");
                            if (values.length <= Math.max(labelIndex, Math.max(elapsedIndex, successIndex))) {
                                continue;
                            }
    
                            String label = values[labelIndex];
                            long elapsed = Long.parseLong(values[elapsedIndex]);
                            boolean success = Boolean.parseBoolean(values[successIndex]);
    
                            // 获取可选字段
                            long timestamp = timestampIndex >= 0 && timestampIndex < values.length ?
                                    Long.parseLong(values[timestampIndex]) : System.currentTimeMillis();
    
                            long receivedBytes = bytesIndex >= 0 && bytesIndex < values.length ?
                                    safeParseLong(values[bytesIndex], 0) : 0;
    
                            long sentBytes = sentBytesIndex >= 0 && sentBytesIndex < values.length ?
                                    safeParseLong(values[sentBytesIndex], 0) : 0;
    
                            // 更新开始和结束时间戳
                            updateTimestampBounds(timestamp, firstTimestamp, lastTimestamp);
    
                            // 更新总请求数和错误数
                            totalSamples.incrementAndGet();
                            if (!success) {
                                totalErrors.incrementAndGet();
                            }
    
                            // 更新各采样器的统计数据
                            updateSamplerStats(samplerStats, label, elapsed, success, timestamp, receivedBytes, sentBytes);
    
                            // 更新总体统计数据
                            updateSamplerStats(samplerStats, "Total", elapsed, success, timestamp, receivedBytes, sentBytes);
    
                            // 更新时间序列数据 (极大降低采样率)
                            if (!skipTimeSeries && timeSeriesMap != null && processedLines % TIME_SERIES_SAMPLING_RATE == 0) {
                                updateTimeSeriesData(timeSeriesMap, label, timestamp, elapsed, success);
                            }
                        }
                    } catch (Exception e) {
                        // 忽略单行解析错误，继续处理其他行
                        if (processedLines % 100000 == 0) {
                            log.warn("忽略错误行: {}", e.getMessage());
                        }
                    }
                } else if (b != '\r') {  // 忽略回车符
                    line.append((char) b);
                }
            }
        }
        
        log.info("文件块 [{}-{}] 处理完成，共处理 {} 行，耗时: {}秒",
                start, end, processedLines, (System.currentTimeMillis() - processStart) / 1000.0);
    }
    
    /**
     * 使用手动解析而非String.split()方法，以提高性能
     */
    private void processLineWithFastParsing(String line, Map<String, SamplerStatistics> samplerStats,
                                          Map<String, Map<Long, TimePoint>> timeSeriesMap,
                                          AtomicLong firstTimestamp, AtomicLong lastTimestamp,
                                          AtomicLong totalSamples, AtomicLong totalErrors,
                                          int labelIndex, int elapsedIndex, int successIndex,
                                          int timestampIndex, int bytesIndex, int sentBytesIndex,
                                          long processedLines, boolean skipTimeSeries) {
        // 手动解析CSV行
        List<String> values = new ArrayList<>();
        StringBuilder field = new StringBuilder(50);
        boolean inQuotes = false;
        
        for (int i = 0; i < line.length(); i++) {
            char c = line.charAt(i);
            
            if (c == '"') {
                inQuotes = !inQuotes;
            } else if (c == ',' && !inQuotes) {
                values.add(field.toString());
                field.setLength(0);
            } else {
                field.append(c);
            }
        }
        
        // 添加最后一个字段
        values.add(field.toString());
        
        // 检查字段数是否足够
        if (values.size() <= Math.max(labelIndex, Math.max(elapsedIndex, successIndex))) {
            return;
        }
        
        // 提取字段值
        String label = values.get(labelIndex);
        long elapsed;
        boolean success;
        
        try {
            elapsed = Long.parseLong(values.get(elapsedIndex));
            success = Boolean.parseBoolean(values.get(successIndex));
        } catch (NumberFormatException e) {
            return; // 跳过无效行
        }
        
        // 获取可选字段
        long timestamp = timestampIndex >= 0 && timestampIndex < values.size() ?
                safeParseLong(values.get(timestampIndex), System.currentTimeMillis()) : System.currentTimeMillis();
        
        long receivedBytes = bytesIndex >= 0 && bytesIndex < values.size() ?
                safeParseLong(values.get(bytesIndex), 0) : 0;
        
        long sentBytes = sentBytesIndex >= 0 && sentBytesIndex < values.size() ?
                safeParseLong(values.get(sentBytesIndex), 0) : 0;
        
        // 更新开始和结束时间戳
        updateTimestampBounds(timestamp, firstTimestamp, lastTimestamp);
        
        // 更新总请求数和错误数
        totalSamples.incrementAndGet();
        if (!success) {
            totalErrors.incrementAndGet();
        }
        
        // 更新各采样器的统计数据
        updateSamplerStats(samplerStats, label, elapsed, success, timestamp, receivedBytes, sentBytes);
        
        // 更新总体统计数据
        updateSamplerStats(samplerStats, "Total", elapsed, success, timestamp, receivedBytes, sentBytes);
        
        // 更新时间序列数据 (低频率采样)
        if (!skipTimeSeries && timeSeriesMap != null && processedLines % TIME_SERIES_SAMPLING_RATE == 0) {
            updateTimeSeriesData(timeSeriesMap, label, timestamp, elapsed, success);
        }
    }

    /**
     * 查找文件中下一个行的开始位置
     */
    private long findNextLineStart(FileChannel channel, long position) throws IOException {
        ByteBuffer buffer = ByteBuffer.allocate(1);
        long pos = position;
        
        while (pos < channel.size()) {
            buffer.clear();
            channel.read(buffer, pos);
            buffer.flip();
            
            if (buffer.hasRemaining() && buffer.get() == '\n') {
                return pos + 1;
            }
            
            pos++;
        }
        
        return -1;  // 没有找到下一行
    }

    /**
     * 更新采样器的统计数据
     */
    private void updateSamplerStats(Map<String, SamplerStatistics> samplerStats,
                                    String label, long elapsed, boolean success,
                                    long timestamp, long receivedBytes, long sentBytes) {

        SamplerStatistics stats = samplerStats.computeIfAbsent(label, k -> new SamplerStatistics());
        stats.addSample(elapsed, success, timestamp, receivedBytes, sentBytes);
    }

    /**
     * 更新时间范围
     */
    private void updateTimestampBounds(long timestamp,
                                       AtomicLong firstTimestamp,
                                       AtomicLong lastTimestamp) {
        // 更新最早时间戳
        long current = firstTimestamp.get();
        while (timestamp < current) {
            if (firstTimestamp.compareAndSet(current, timestamp)) {
                break;
            }
            current = firstTimestamp.get();
        }

        // 更新最晚时间戳
        current = lastTimestamp.get();
        while (timestamp > current) {
            if (lastTimestamp.compareAndSet(current, timestamp)) {
                break;
            }
            current = lastTimestamp.get();
        }
    }

    /**
     * 更新时间序列数据
     */
    private void updateTimeSeriesData(Map<String, Map<Long, TimePoint>> timeSeriesMap,
                                      String label, long timestamp, long elapsed, boolean success) {
        // 按10秒汇总，减少数据点
        long timeKey = timestamp / 10000 * 10000;

        Map<Long, TimePoint> samplerTimeSeries = timeSeriesMap.computeIfAbsent(
                label, k -> new ConcurrentHashMap<>());

        TimePoint timePoint = samplerTimeSeries.computeIfAbsent(
                timeKey, k -> new TimePoint());

        timePoint.addSample(elapsed, success);
    }

    /**
     * 生成时间序列数据的JSON对象
     */
    private JSONObject generateTimeSeriesData(Map<Long, TimePoint> timePointMap) {
        JSONObject timeSeriesJson = new JSONObject();

        List<Long> sortedTimestamps = new ArrayList<>(timePointMap.keySet());
        Collections.sort(sortedTimestamps);

        // 如果数据点过多，则进行降采样
        if (sortedTimestamps.size() > MAX_TIME_SERIES_POINTS) {
            int step = sortedTimestamps.size() / MAX_TIME_SERIES_POINTS;
            List<Long> sampledTimestamps = new ArrayList<>();
            for (int i = 0; i < sortedTimestamps.size(); i += step) {
                sampledTimestamps.add(sortedTimestamps.get(i));
            }
            sortedTimestamps = sampledTimestamps;
        }

        JSONArray timestampsJson = new JSONArray();
        JSONArray tpsJson = new JSONArray();
        JSONArray avgResponseTimesJson = new JSONArray();
        JSONArray errorRatesJson = new JSONArray();

        for (Long timestamp : sortedTimestamps) {
            TimePoint point = timePointMap.get(timestamp);

            timestampsJson.add(timestamp);
            tpsJson.add(formatDecimal(point.getSampleCount() / 10.0)); // 10秒内的请求数除以10得到TPS
            avgResponseTimesJson.add(formatDecimal(point.getAverageResponseTime()));
            errorRatesJson.add(formatDecimal(point.getErrorRate()));
        }

        timeSeriesJson.put("timestamps", timestampsJson);
        timeSeriesJson.put("tps", tpsJson);
        timeSeriesJson.put("avgResponseTimes", avgResponseTimesJson);
        timeSeriesJson.put("errorRates", errorRatesJson);

        return timeSeriesJson;
    }

    /**
     * 生成完整的ReportDO对象(用于与现有系统集成)
     */
    public ReportDO generateFullReport(TaskDO taskDO, String jtlPath, JFileDO reportFile) {
        JSONObject statsJson = processFast(taskDO, jtlPath, null);
        if (statsJson == null) {
            return null;
        }

        // 从快速处理结果创建完整报告
        Map<String, List<JSONObject>> dashBoardData = new HashMap<>();
        Map<String, JSONObject> graphData = new HashMap<>();

        // 构建统计表格
        buildStatisticsTable(statsJson, dashBoardData);

        // 构建图表数据
        buildGraphData(statsJson, graphData);

        // 创建报告对象
        ReportDO reportDO = new ReportDO();
        reportDO.setTaskId(taskDO.getTaskId());
        reportDO.setGraphData(graphData);
        reportDO.setDashBoardData(dashBoardData);
        reportDO.setFile(reportFile);
        reportDO.setCaseId(taskDO.getJmeterCase());
        reportDO.setCreateTime(taskDO.getCreateTime());
        reportDO.setResult(taskDO.getResult());

        return reportDO;
    }

    /**
     * 构建统计表格
     */
    private void buildStatisticsTable(JSONObject statsJson, Map<String, List<JSONObject>> dashBoardData) {
        List<JSONObject> statisticsTable = new ArrayList<>();

        JSONObject samplersJson = statsJson.getJSONObject("samplers");
        long firstTimestamp = statsJson.getLongValue("firstTimestamp");
        long lastTimestamp = statsJson.getLongValue("lastTimestamp");

        // 首先添加Total行
        if (samplersJson.containsKey("Total")) {
            JSONObject totalJson = samplersJson.getJSONObject("Total");
            // 添加时间戳信息到采样器JSON
            totalJson.put("firstTimestamp", firstTimestamp);
            totalJson.put("lastTimestamp", lastTimestamp);
            JSONObject totalRow = createStatisticsRow("Total", totalJson);
            statisticsTable.add(totalRow);
        }

        // 添加其他采样器行
        for (String label : samplersJson.keySet()) {
            if (!"Total".equals(label)) {
                JSONObject samplerJson = samplersJson.getJSONObject(label);
                // 添加时间戳信息到采样器JSON
                samplerJson.put("firstTimestamp", firstTimestamp);
                samplerJson.put("lastTimestamp", lastTimestamp);
                JSONObject row = createStatisticsRow(label, samplerJson);
                statisticsTable.add(row);
            }
        }

        dashBoardData.put("statisticsTable", statisticsTable);
    }

    /**
     * 构建统计表格 (用于合并预处理统计文件)
     */
    private void buildStatisticsTable(Map<String, JSONObject> samplerStats, List<JSONObject> statisticsTable, 
                                     long firstTimestamp, long lastTimestamp) {
        // 首先添加Total行
        if (samplerStats.containsKey("Total")) {
            JSONObject totalJson = samplerStats.get("Total");
            JSONObject totalRow = createStatisticsRow("Total", totalJson, firstTimestamp, lastTimestamp);
            statisticsTable.add(totalRow);
        }

        // 添加其他采样器行
        for (String label : samplerStats.keySet()) {
            if (!"Total".equals(label)) {
                JSONObject samplerJson = samplerStats.get(label);
                JSONObject row = createStatisticsRow(label, samplerJson, firstTimestamp, lastTimestamp);
                statisticsTable.add(row);
            }
        }
    }

    /**
     * 创建统计表格行
     */
    private JSONObject createStatisticsRow(String label, JSONObject samplerJson) {
        JSONObject row = new JSONObject();
        row.put("label", label);
        row.put("samples", samplerJson.getLongValue("samples"));
        row.put("fail", samplerJson.getLongValue("errors"));
        row.put("error", formatPercentage(samplerJson.getDoubleValue("errorRate")));
        row.put("average", formatDecimal(samplerJson.getDoubleValue("avgTime")));
        row.put("min", samplerJson.getLongValue("minTime"));
        row.put("max", samplerJson.getLongValue("maxTime"));

        // 添加百分位数据
        JSONObject percentiles = samplerJson.getJSONObject("percentiles");
        row.put("median", formatDecimal(percentiles.getDoubleValue("50.0")));
        row.put("90th", formatDecimal(percentiles.getDoubleValue("90.0")));
        row.put("95th", formatDecimal(percentiles.getDoubleValue("95.0")));
        row.put("99th", formatDecimal(percentiles.getDoubleValue("99.0")));

        // 从父方法传入时间戳而不是直接访问statsJson
        if (samplerJson.containsKey("firstTimestamp") && samplerJson.containsKey("lastTimestamp")) {
            // 计算TPS
            long samples = samplerJson.getLongValue("samples");
            long firstTimestamp = samplerJson.getLongValue("firstTimestamp");
            long lastTimestamp = samplerJson.getLongValue("lastTimestamp");
            double durationSeconds = (lastTimestamp - firstTimestamp) / 1000.0;
            double tps = durationSeconds > 0 ? samples / durationSeconds : 0;
            row.put("transactions", formatDecimal(tps));

            // 计算网络吞吐量
            long receivedBytes = samplerJson.getLongValue("receivedBytes");
            long sentBytes = samplerJson.getLongValue("sentBytes");
            double receivedKBps = durationSeconds > 0 ? (receivedBytes / 1024.0) / durationSeconds : 0;
            double sentKBps = durationSeconds > 0 ? (sentBytes / 1024.0) / durationSeconds : 0;
            row.put("received", formatDecimal(receivedKBps));
            row.put("Sent", formatDecimal(sentKBps));
        } else {
            // 默认值
            row.put("transactions", 0);
            row.put("received", 0);
            row.put("Sent", 0);
        }

        return row;
    }
    
    /**
     * 创建统计表格行 (用于合并预处理统计文件)
     */
    private JSONObject createStatisticsRow(String label, JSONObject samplerJson, long firstTimestamp, long lastTimestamp) {
        JSONObject row = new JSONObject();
        row.put("label", label);
        row.put("samples", samplerJson.getLongValue("samples"));
        row.put("fail", samplerJson.getLongValue("errors"));
        
        // 计算错误率
        long samples = samplerJson.getLongValue("samples");
        long errors = samplerJson.getLongValue("errors");
        double errorRate = samples > 0 ? (double) errors / samples * 100 : 0;
        row.put("error", formatPercentage(errorRate));
        
        // 计算平均响应时间
        double sumTime = samplerJson.getDoubleValue("sumTime");
        double avgTime = samples > 0 ? sumTime / samples : 0;
        row.put("average", formatDecimal(avgTime));
        
        row.put("min", samplerJson.getLongValue("minTime"));
        row.put("max", samplerJson.getLongValue("maxTime"));

        // 添加百分位数据
        if (samplerJson.containsKey("percentiles")) {
            JSONObject percentiles = samplerJson.getJSONObject("percentiles");
            row.put("median", formatDecimal(percentiles.getDoubleValue("50.0")));
            row.put("90th", formatDecimal(percentiles.getDoubleValue("90.0")));
            row.put("95th", formatDecimal(percentiles.getDoubleValue("95.0")));
            row.put("99th", formatDecimal(percentiles.getDoubleValue("99.0")));
        } else {
            // 如果没有百分位数据，则使用平均值
            row.put("median", formatDecimal(avgTime));
            row.put("90th", formatDecimal(avgTime));
            row.put("95th", formatDecimal(avgTime));
            row.put("99th", formatDecimal(avgTime));
        }

        // 计算TPS
        double durationSeconds = (lastTimestamp - firstTimestamp) / 1000.0;
        double tps = durationSeconds > 0 ? samples / durationSeconds : 0;
        row.put("transactions", formatDecimal(tps));

        // 计算网络吞吐量
        long receivedBytes = samplerJson.getLongValue("receivedBytes");
        long sentBytes = samplerJson.getLongValue("sentBytes");
        double receivedKBps = durationSeconds > 0 ? (receivedBytes / 1024.0) / durationSeconds : 0;
        double sentKBps = durationSeconds > 0 ? (sentBytes / 1024.0) / durationSeconds : 0;
        row.put("received", formatDecimal(receivedKBps));
        row.put("Sent", formatDecimal(sentKBps));

        return row;
    }

    /**
     * 构建图表数据
     */
    private void buildGraphData(JSONObject statsJson, Map<String, JSONObject> graphData) {
        JSONObject samplersJson = statsJson.getJSONObject("samplers");

        // 响应时间图表
        JSONObject responseTimesOverTime = new JSONObject();
        responseTimesOverTime.put("titleCN", "平均响应时间");
        responseTimesOverTime.put("yName", "平均响应时间(ms)");
        List<JSONObject> rtSeries = new ArrayList<>();
        List<String> rtLabels = new ArrayList<>();

        // TPS图表
        JSONObject transactionsPerSecond = new JSONObject();
        transactionsPerSecond.put("titleCN", "TPS");
        transactionsPerSecond.put("yName", "事务数/秒");
        List<JSONObject> tpsSeries = new ArrayList<>();
        List<String> tpsLabels = new ArrayList<>();

        // 为每个采样器添加系列
        for (String label : samplersJson.keySet()) {
            JSONObject samplerJson = samplersJson.getJSONObject(label);

            if (samplerJson.containsKey("timeSeriesData")) {
                JSONObject timeSeriesData = samplerJson.getJSONObject("timeSeriesData");

                // 响应时间系列
                JSONObject rtSerie = new JSONObject();
                rtSerie.put("label", label);
                rtSerie.put("name", label);
                rtSerie.put("type", "line");

                // 构建格式化的数据点
                List<List<Object>> rtData = new ArrayList<>();
                JSONArray timestamps = timeSeriesData.getJSONArray("timestamps");
                JSONArray avgResponseTimes = timeSeriesData.getJSONArray("avgResponseTimes");

                for (int i = 0; i < timestamps.size(); i++) {
                    rtData.add(Arrays.asList(
                            timestamps.getLongValue(i),
                            formatDecimal(avgResponseTimes.getDoubleValue(i))
                    ));
                }

                rtSerie.put("data", rtData);
                rtSeries.add(rtSerie);
                rtLabels.add(label);

                // TPS系列
                JSONObject tpsSerie = new JSONObject();
                tpsSerie.put("label", label);
                tpsSerie.put("name", label);
                tpsSerie.put("type", "line");

                List<List<Object>> tpsData = new ArrayList<>();
                JSONArray tpsValues = timeSeriesData.getJSONArray("tps");

                for (int i = 0; i < timestamps.size(); i++) {
                    tpsData.add(Arrays.asList(
                            timestamps.getLongValue(i),
                            formatDecimal(tpsValues.getDoubleValue(i))
                    ));
                }

                tpsSerie.put("data", tpsData);
                tpsSeries.add(tpsSerie);
                tpsLabels.add(label);
            }
        }

        responseTimesOverTime.put("series", rtSeries);
        responseTimesOverTime.put("labels", rtLabels);

        transactionsPerSecond.put("series", tpsSeries);
        transactionsPerSecond.put("labels", tpsLabels);

        graphData.put("responseTimesOverTimeInfos", responseTimesOverTime);
        graphData.put("transactionsPerSecondInfos", transactionsPerSecond);
        graphData.put("totalTPSInfos", transactionsPerSecond); // 兼容原有格式
    }

    /**
     * 构建图表数据 (用于合并预处理统计文件)
     */
    private void buildGraphData(Map<String, Map<Long, Double>> tpsDataMap, 
                               Map<String, Map<Long, Double>> rtDataMap,
                               Map<String, JSONObject> graphData) {
        // 处理TPS数据
        processTpsData(tpsDataMap, graphData);
        
        // 处理响应时间数据
        processRtData(rtDataMap, graphData);
    }
    
    /**
     * 处理TPS数据
     */
    private void processTpsData(Map<String, Map<Long, Double>> tpsDataMap, Map<String, JSONObject> graphData) {
        for (Map.Entry<String, Map<Long, Double>> entry : tpsDataMap.entrySet()) {
            String label = entry.getKey();
            Map<Long, Double> timePoints = entry.getValue();
            
            // 按时间戳排序
            List<Long> timestamps = new ArrayList<>(timePoints.keySet());
            Collections.sort(timestamps);
            
            JSONArray categories = new JSONArray();
            JSONArray series = new JSONArray();
            
            for (Long timestamp : timestamps) {
                // 添加时间戳作为X轴类别
                categories.add(timestamp);
                
                // 添加TPS值作为Y轴数据点
                series.add(formatDecimal(timePoints.get(timestamp)));
            }
            
            JSONObject tpsData = new JSONObject();
            tpsData.put("categories", categories);
            tpsData.put("series", series);
            
            String graphKey = "tps_" + label;
            graphData.put(graphKey, tpsData);
        }
    }
    
    /**
     * 处理响应时间数据
     */
    private void processRtData(Map<String, Map<Long, Double>> rtDataMap, Map<String, JSONObject> graphData) {
        for (Map.Entry<String, Map<Long, Double>> entry : rtDataMap.entrySet()) {
            String label = entry.getKey();
            Map<Long, Double> timePoints = entry.getValue();
            
            // 按时间戳排序
            List<Long> timestamps = new ArrayList<>(timePoints.keySet());
            Collections.sort(timestamps);
            
            JSONArray categories = new JSONArray();
            JSONArray series = new JSONArray();
            
            for (Long timestamp : timestamps) {
                // 添加时间戳作为X轴类别
                categories.add(timestamp);
                
                // 添加响应时间值作为Y轴数据点
                series.add(formatDecimal(timePoints.get(timestamp)));
            }
            
            JSONObject rtData = new JSONObject();
            rtData.put("categories", categories);
            rtData.put("series", series);
            
            String graphKey = "rt_" + label;
            graphData.put(graphKey, rtData);
        }
    }

    /**
     * 生成预处理统计文件（用于Agent端本地处理）
     */
    public String generateStatsFile(TaskDO taskDO, String jtlPath, String agentAddress) {
        log.info("开始为任务 {} 生成统计文件，处理JTL文件: {}", taskDO.getTaskId(), jtlPath);
        long startTime = System.currentTimeMillis();
        
        JSONObject statsJson = processFast(taskDO, jtlPath, null);
        if (statsJson == null) {
            return null;
        }

        try {
            String outputPath = Paths.get(
                    System.getProperty("java.io.tmpdir"),
                    "stats_" + taskDO.getTaskId() + "_" + agentAddress + ".json"
            ).toString();

            try (BufferedWriter writer = new BufferedWriter(new FileWriter(outputPath), BUFFER_SIZE / 2)) {
                writer.write(statsJson.toJSONString());
            }

            log.info("成功生成统计文件: {}，耗时: {}秒", outputPath, (System.currentTimeMillis() - startTime) / 1000.0);
            return outputPath;

        } catch (Exception e) {
            log.error("生成统计文件失败: {}", e.getMessage(), e);
            return null;
        }
    }

    // 辅助类和方法

    /**
     * 采样器统计信息类
     */
    private static class SamplerStatistics {
        private final AtomicLong sampleCount = new AtomicLong(0);
        private final AtomicLong errorCount = new AtomicLong(0);
        private final AtomicLong totalElapsedTime = new AtomicLong(0);
        private final AtomicLong minResponseTime = new AtomicLong(Long.MAX_VALUE);
        private final AtomicLong maxResponseTime = new AtomicLong(0);
        private final AtomicLong receivedBytes = new AtomicLong(0);
        private final AtomicLong sentBytes = new AtomicLong(0);

        // 使用并发集合进行有限采样
        private final Queue<Long> responseTimes = new ConcurrentLinkedQueue<>();

        public void addSample(long elapsed, boolean success, long timestamp,
                              long received, long sent) {
            // 更新基本计数
            sampleCount.incrementAndGet();
            if (!success) {
                errorCount.incrementAndGet();
            }

            // 累加总响应时间
            totalElapsedTime.addAndGet(elapsed);

            // 更新最小响应时间
            long current = minResponseTime.get();
            while (elapsed < current) {
                if (minResponseTime.compareAndSet(current, elapsed)) {
                    break;
                }
                current = minResponseTime.get();
            }

            // 更新最大响应时间
            current = maxResponseTime.get();
            while (elapsed > current) {
                if (maxResponseTime.compareAndSet(current, elapsed)) {
                    break;
                }
                current = maxResponseTime.get();
            }

            // 累计网络字节数
            receivedBytes.addAndGet(received);
            sentBytes.addAndGet(sent);

            // 采样保存响应时间用于百分位计算
            if (responseTimes.size() < MAX_PERCENTILE_SAMPLES) {
                responseTimes.add(elapsed);
            } else if (Math.random() < 0.1) { // 10%的概率替换
                // 随机丢弃一个现有样本并添加新样本
                if (!responseTimes.isEmpty()) {
                    responseTimes.poll();
                }
                responseTimes.add(elapsed);
            }
        }

        /**
         * 按照采样比例调整统计数据，用于极限采样模式
         */
        public void adjustForSampling(int samplingRate) {
            if (samplingRate <= 1) {
                return;  // 不需要调整
            }
            
            // 调整样本数和错误数
            sampleCount.set(sampleCount.get() * samplingRate);
            errorCount.set(errorCount.get() * samplingRate);
            
            // 字节数也需要调整
            receivedBytes.set(receivedBytes.get() * samplingRate);
            sentBytes.set(sentBytes.get() * samplingRate);
            
            // 总响应时间需要调整
            totalElapsedTime.set(totalElapsedTime.get() * samplingRate);
            
            // 最大最小值和百分位数不需要调整
        }

        public long getSampleCount() {
            return sampleCount.get();
        }

        public long getErrorCount() {
            return errorCount.get();
        }

        public double getErrorRate() {
            long samples = sampleCount.get();
            return samples == 0 ? 0 : (double) errorCount.get() / samples * 100;
        }

        public double getAverageResponseTime() {
            long samples = sampleCount.get();
            return samples == 0 ? 0 : (double) totalElapsedTime.get() / samples;
        }

        public long getMinResponseTime() {
            long min = minResponseTime.get();
            return min == Long.MAX_VALUE ? 0 : min;
        }

        public long getMaxResponseTime() {
            return maxResponseTime.get();
        }

        public double getPercentile(int percentile) {
            List<Long> times = new ArrayList<>(responseTimes);
            if (times.isEmpty()) {
                return 0;
            }

            Collections.sort(times);
            int index = (int) Math.ceil(percentile / 100.0 * times.size()) - 1;
            if (index < 0) index = 0;
            if (index >= times.size()) index = times.size() - 1;

            return times.get(index);
        }

        public long getReceivedBytes() {
            return receivedBytes.get();
        }

        public long getSentBytes() {
            return sentBytes.get();
        }
    }

    /**
     * 时间点数据类
     */
    private static class TimePoint {
        private final AtomicLong sampleCount = new AtomicLong(0);
        private final AtomicLong errorCount = new AtomicLong(0);
        private final AtomicLong totalElapsedTime = new AtomicLong(0);

        public void addSample(long elapsed, boolean success) {
            sampleCount.incrementAndGet();
            if (!success) {
                errorCount.incrementAndGet();
            }
            totalElapsedTime.addAndGet(elapsed);
        }

        public long getSampleCount() {
            return sampleCount.get();
        }

        public double getAverageResponseTime() {
            long samples = sampleCount.get();
            return samples == 0 ? 0 : (double) totalElapsedTime.get() / samples;
        }

        public double getErrorRate() {
            long samples = sampleCount.get();
            return samples == 0 ? 0 : (double) errorCount.get() / samples * 100;
        }
    }

    // 工具方法

    private int findColumnIndex(String[] headers, String columnName) {
        return findColumnIndex(headers, columnName, false);
    }

    private int findColumnIndex(String[] headers, String columnName, boolean allowMissing) {
        for (int i = 0; i < headers.length; i++) {
            if (headers[i].equals(columnName)) {
                return i;
            }
        }
        if (allowMissing) {
            return -1;
        }
        throw new IllegalArgumentException("找不到列: " + columnName);
    }

    private long safeParseLong(String value, long defaultValue) {
        try {
            return Long.parseLong(value);
        } catch (NumberFormatException e) {
            return defaultValue;
        }
    }

    private double formatDecimal(double value) {
        return new BigDecimal(value).setScale(2, RoundingMode.HALF_UP).doubleValue();
    }

    private String formatPercentage(double value) {
        return new BigDecimal(value).setScale(2, RoundingMode.HALF_UP).toString() + "%";
    }
    /**
     * 使用统计文件合并生成报告（服务端）
     */
    public ReportDO mergeStatsFiles(TaskDO taskDO, List<JFileDO> statsFiles, JFileService jFileService, JFileDO reportFile) {
        log.info("开始合并 {} 个预处理统计文件", statsFiles.size());

        if (statsFiles.isEmpty()) {
            log.warn("任务 {} 没有找到预处理统计文件", taskDO.getTaskId());
            return null;
        }
        try {
            // 初始化报告数据结构
            Map<String, List<JSONObject>> dashBoardData = new HashMap<>();
            Map<String, JSONObject> graphData = new HashMap<>();

            // 保存每个采样器的全局统计信息
            Map<String, JSONObject> samplerStats = new HashMap<>();

            // 按采样器名称保存各接口的时间序列数据
            Map<String, Map<Long, Double>> tpsDataMap = new HashMap<>();
            Map<String, Map<Long, Double>> rtDataMap = new HashMap<>();

            // 记录时间范围和总体统计
            long totalSamples = 0;
            long totalErrors = 0;
            long firstTimestamp = Long.MAX_VALUE;
            long lastTimestamp = 0;

            // 下载并处理每个统计文件
            for (JFileDO statsFile : statsFiles) {
                log.info("处理统计文件: {}", statsFile.getName());

                // 下载统计文件
                String statsFilePath = jFileService.downloadFile(statsFile.getId(), jFileService.getStoreDir());
                if (statsFilePath == null) {
                    log.error("下载统计文件失败: {}", statsFile.getName());
                    continue;
                }

                try {
                    // 读取JSON统计数据
                    String jsonContent = new String(Files.readAllBytes(Paths.get(statsFilePath)));
                    JSONObject statsJson = JSONObject.parseObject(jsonContent);

                    // 更新总体统计
                    totalSamples += statsJson.getLongValue("totalSamples", 0);
                    totalErrors += statsJson.getLongValue("totalErrors", 0);

                    // 更新时间范围
                    if (statsJson.containsKey("firstTimestamp")) {
                        long timestamp = statsJson.getLongValue("firstTimestamp");
                        if (timestamp < firstTimestamp) {
                            firstTimestamp = timestamp;
                        }
                    }
                    if (statsJson.containsKey("lastTimestamp")) {
                        long timestamp = statsJson.getLongValue("lastTimestamp");
                        if (timestamp > lastTimestamp) {
                            lastTimestamp = timestamp;
                        }
                    }

                    // 合并采样器统计数据
                    if (statsJson.containsKey("samplers")) {
                        JSONObject samplers = statsJson.getJSONObject("samplers");
                        mergeSamplerStats(samplers, samplerStats, tpsDataMap, rtDataMap);
                    }

                } catch (Exception e) {
                    log.error("处理统计文件数据失败: {}, 错误: {}", statsFile.getName(), e.getMessage(), e);
                } finally {
                    // 清理临时文件
                    try {
                        Files.deleteIfExists(Paths.get(statsFilePath));
                    } catch (IOException e) {
                        log.warn("删除临时统计文件失败: {}", statsFilePath, e);
                    }
                }
            }

            // 生成统计表格
            List<JSONObject> statisticsTable = new ArrayList<>();
            buildStatisticsTable(samplerStats, statisticsTable, firstTimestamp, lastTimestamp);
            dashBoardData.put("statisticsTable", statisticsTable);

            // 构建图表数据
            buildGraphData(tpsDataMap, rtDataMap, graphData);

            // 创建最终报告对象
            ReportDO reportDO = new ReportDO();
            reportDO.setTaskId(taskDO.getTaskId());
            reportDO.setGraphData(graphData);
            reportDO.setDashBoardData(dashBoardData);
            reportDO.setFile(reportFile);
            reportDO.setCaseId(taskDO.getJmeterCase());
            reportDO.setCreateTime(taskDO.getCreateTime());
            reportDO.setResult(taskDO.getResult());

            log.info("预处理统计文件合并完成，共 {} 个采样器", samplerStats.size());
            return reportDO;

        } catch (Exception e) {
            log.error("合并预处理统计文件失败: {}", e.getMessage(), e);
            return null;
        }
    }

    // 辅助方法，合并采样器统计数据
    private void mergeSamplerStats(JSONObject samplers, Map<String, JSONObject> samplerStats,
                                   Map<String, Map<Long, Double>> tpsDataMap, Map<String, Map<Long, Double>> rtDataMap) {
        for (String label : samplers.keySet()) {
            JSONObject sampler = samplers.getJSONObject(label);

            if (!samplerStats.containsKey(label)) {
                samplerStats.put(label, new JSONObject());
                samplerStats.get(label).put("label", label);
                samplerStats.get(label).put("samples", 0L);
                samplerStats.get(label).put("errors", 0L);
                samplerStats.get(label).put("minTime", Long.MAX_VALUE);
                samplerStats.get(label).put("maxTime", 0L);
                samplerStats.get(label).put("sumTime", 0.0);
                samplerStats.get(label).put("receivedBytes", 0L);
                samplerStats.get(label).put("sentBytes", 0L);
            }

            JSONObject currentStats = samplerStats.get(label);

            // 更新样本数和错误数
            long currentSamples = currentStats.getLongValue("samples");
            long currentErrors = currentStats.getLongValue("errors");
            long newSamples = sampler.getLongValue("samples");
            long newErrors = sampler.getLongValue("errors");
            currentStats.put("samples", currentSamples + newSamples);
            currentStats.put("errors", currentErrors + newErrors);

            // 更新响应时间统计
            long currentMinTime = currentStats.getLongValue("minTime");
            long newMinTime = sampler.getLongValue("minTime");
            if (newMinTime < currentMinTime) {
                currentStats.put("minTime", newMinTime);
            }

            long currentMaxTime = currentStats.getLongValue("maxTime");
            long newMaxTime = sampler.getLongValue("maxTime");
            if (newMaxTime > currentMaxTime) {
                currentStats.put("maxTime", newMaxTime);
            }

            // 累计响应时间总和用于计算加权平均
            double currentSumTime = currentStats.getDoubleValue("sumTime");
            double newAvgTime = sampler.getDoubleValue("avgTime");
            currentStats.put("sumTime", currentSumTime + (newAvgTime * newSamples));

            // 更新百分位数据
            if (sampler.containsKey("percentiles")) {
                mergePercentiles(currentStats, sampler, newSamples);
            }

            // 更新网络字节数
            if (sampler.containsKey("receivedBytes")) {
                long currentReceivedBytes = currentStats.getLongValue("receivedBytes");
                long newReceivedBytes = sampler.getLongValue("receivedBytes");
                currentStats.put("receivedBytes", currentReceivedBytes + newReceivedBytes);
            }

            if (sampler.containsKey("sentBytes")) {
                long currentSentBytes = currentStats.getLongValue("sentBytes");
                long newSentBytes = sampler.getLongValue("sentBytes");
                currentStats.put("sentBytes", currentSentBytes + newSentBytes);
            }

            // 合并时间序列数据
            if (sampler.containsKey("timeSeriesData")) {
                mergeTimeSeriesData(label, sampler.getJSONObject("timeSeriesData"), tpsDataMap, rtDataMap);
            }
        }
    }

    // 合并百分位数据
    private void mergePercentiles(JSONObject currentStats, JSONObject sampler, long newSamples) {
        JSONObject percentiles = sampler.getJSONObject("percentiles");
        long weightedCount = currentStats.getLongValue("weightedCount", 0);

        // 初始化百分位数据
        if (!currentStats.containsKey("median")) currentStats.put("median", 0.0);
        if (!currentStats.containsKey("90th")) currentStats.put("90th", 0.0);
        if (!currentStats.containsKey("95th")) currentStats.put("95th", 0.0);
        if (!currentStats.containsKey("99th")) currentStats.put("99th", 0.0);

        // 中位数加权平均
        double currentMedian = currentStats.getDoubleValue("median");
        double newMedian = percentiles.getDoubleValue("50.0");
        double weightedMedian = (currentMedian * weightedCount + newMedian * newSamples) / (weightedCount + newSamples);
        currentStats.put("median", weightedMedian);

        // 90th百分位加权平均
        double current90th = currentStats.getDoubleValue("90th");
        double new90th = percentiles.getDoubleValue("90.0");
        double weighted90th = (current90th * weightedCount + new90th * newSamples) / (weightedCount + newSamples);
        currentStats.put("90th", weighted90th);

        // 95th百分位加权平均
        double current95th = currentStats.getDoubleValue("95th");
        double new95th = percentiles.getDoubleValue("95.0");
        double weighted95th = (current95th * weightedCount + new95th * newSamples) / (weightedCount + newSamples);
        currentStats.put("95th", weighted95th);

        // 99th百分位加权平均
        double current99th = currentStats.getDoubleValue("99th");
        double new99th = percentiles.getDoubleValue("99.0");
        double weighted99th = (current99th * weightedCount + new99th * newSamples) / (weightedCount + newSamples);
        currentStats.put("99th", weighted99th);

        // 更新权重计数
        currentStats.put("weightedCount", weightedCount + newSamples);
    }

    // 合并时间序列数据
    private void mergeTimeSeriesData(String label, JSONObject timeSeriesData,
                                     Map<String, Map<Long, Double>> tpsDataMap, Map<String, Map<Long, Double>> rtDataMap) {
        if (!timeSeriesData.containsKey("timestamps") ||
                !timeSeriesData.containsKey("tps") ||
                !timeSeriesData.containsKey("avgResponseTimes")) {
            return;
        }

        // 初始化映射
        if (!tpsDataMap.containsKey(label)) {
            tpsDataMap.put(label, new TreeMap<>());
        }
        if (!rtDataMap.containsKey(label)) {
            rtDataMap.put(label, new TreeMap<>());
        }

        JSONArray timestamps = timeSeriesData.getJSONArray("timestamps");
        JSONArray tpsValues = timeSeriesData.getJSONArray("tps");
        JSONArray rtValues = timeSeriesData.getJSONArray("avgResponseTimes");

        int minSize = Math.min(timestamps.size(), Math.min(tpsValues.size(), rtValues.size()));

        // 添加到映射
        for (int i = 0; i < minSize; i++) {
            long ts = timestamps.getLongValue(i);
            double tpsVal = tpsValues.getDoubleValue(i);
            double rtVal = rtValues.getDoubleValue(i);

            tpsDataMap.get(label).put(ts, tpsVal);
            rtDataMap.get(label).put(ts, rtVal);
        }
    }
}
